package com.huika.renrench.support.helps;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Type;
import java.net.HttpURLConnection;
import java.net.URL;

import org.json.JSONException;
import org.json.JSONObject;

import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.net.Uri;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.android.volley.Response.ErrorListener;
import com.android.volley.Response.Listener;
import com.android.volley.VolleyError;
import com.google.gson.reflect.TypeToken;
import com.hk.app.android.lib.http.VolleyRequestManager;
import com.huika.lib.ui.framelayout.KJActivityManager;
import com.huika.lib.utils.DebugTool;
import com.huika.lib.utils.NetUtil;
import com.huika.renrench.R;
import com.huika.renrench.config.UrlConstants;
import com.huika.renrench.http.FormResultRequest;
import com.huika.renrench.http.JSONWrapAjaxParams;
import com.huika.renrench.http.RequestResult;
import com.huika.renrench.http.ServerFlagError;
import com.huika.renrench.http.ServerJsonUnParseError;
import com.huika.renrench.support.bean.VersionBean;
import com.huika.renrench.utils.PreferencesHelper;
import com.huika.renrench.utils.ProgressBeanUtil;

/**
 * @description：版本管理类；
 * @author samy
 * @date 2014年10月10日 下午12:19:15
 */
public class VersionManager {
	/**防止多次点击检查更新*/
	private boolean updating;
	private Context context;
	// private long updateTime;
	private Object lock = new Object();
	/** 是否用户自行更新 */
	private boolean isSilent = true;
	/** 判断是否是自动检查 */
	private boolean isZi = true;
	/** 对话框 */
	private Dialog updateDialog;
	/** 是否取消更新 */
	private volatile boolean isCancel = false;

	/** 本地当前版本信息 */
	private PackageInfo currentVerInfo;
	/** 服务器最新版本信息 */
	private VersionBean latestVerInfo;

	/** 本地保存目录 */
	private static String localDir = Environment.getExternalStorageDirectory().getPath() + "/pmall/update/";
	/** 本地保存文件名 */
	private static String localFileName = "pmall.apk";

	/** 进度条 */
	private ProgressBar downloadBar;
	/** 进度值 */
	private TextView progressTv;
	private int fileSize;

	// 获取新版本信息
	private static final int HANDLER_GET_LATEST_VERSION = 11;
	private static final int HANDLER_DOWNLOAD_PROGRESS = 12;
	private static final int HANDLER_DOWNLOAD_FINISH = 13;
	private static final int HANDLER_DOWNLOAD_ERROR = 14;
	private static final int HANDLER_DOWNLOAD_SIZE = 15;
	private static final int HANDLER_DOWNLOAD_STOP = 16;

	private Handler handler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			switch (msg.what) {
				case HANDLER_GET_LATEST_VERSION:
					if (updateDialog != null && updateDialog.isShowing()) {
						updateDialog.dismiss();
					}
					// 获取最新版本
					if (isCancel) {
						break;
					}
					// 比较新版本与当前版本
					compareVersion();
					break;
				case HANDLER_DOWNLOAD_SIZE:
					downloadBar.setMax(fileSize);
					break;
				case HANDLER_DOWNLOAD_PROGRESS:
					// 更新进度
					int downLen = msg.arg1;
					progressTv.setText(downLen * 100 / fileSize + "%");
					downloadBar.setProgress(downLen);
					break;
				case HANDLER_DOWNLOAD_FINISH:
					// 下载完成,转到安装界面
					installApkByPath(context, new File(localDir, localFileName).getAbsolutePath());
					updateDialog.dismiss();
					break;
				case HANDLER_DOWNLOAD_STOP:
					if (updateDialog.isShowing()) {
						updateDialog.dismiss();
					}
					break;
				case HANDLER_DOWNLOAD_ERROR:
					// 下载发生错误
					String errMsg = (String) msg.obj;
					if (errMsg == null || errMsg.length() <= 0) {
						errMsg = "更新失败！";
					}
					Toast.makeText(context, errMsg, Toast.LENGTH_SHORT).show();
					if (updateDialog != null && updateDialog.isShowing()) {
						updateDialog.dismiss();
					}
					break;
				default:
					break;
			}
		}
	};

	public VersionManager(Context context) {
		super();
		this.context = context;
	} 

	/**
	 * @description：检查版本更新;isSilent 是否自动检查更新
	 * @author samy
	 * @date 2014年10月9日 下午6:12:18
	 */
	public void checkVersion(boolean isSilent ,boolean isZi) {
		setSilent(isSilent);
		this.isZi = isZi;
		if (!NetUtil.isNetworkAvailable(context)) { return; }
		if (!isSilent() && isZi) {
			// updateDialog = new AlertDialog.Builder(context).setCancelable(false).setCancelable(false).setTitle("提示")
			// .setMessage("正在检查新版本，请稍候...").setNegativeButton("取消", new OnClickListener() {
			// @Override
			// public void onClick(DialogInterface dialog, int which) {
			// // 取消升级
			// isCancel = true;
			// }
			// }).create();
			// updateDialog.show();
			// 显示检查版本更新中的提示框
			// TODO
			updateDialog = new Dialog(context, R.style.MMTheme);
			RotateAnimation rotate = new RotateAnimation(0f, 359f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
			rotate.setRepeatCount(-1);
			rotate.setDuration(1500);
			updateDialog.setContentView(R.layout.dialog_updating);
			updateDialog.findViewById(R.id.update_loading_iv).startAnimation(rotate);
			// view.findViewById(R.id.update_dialog_close).setOnClickListener(new View.OnClickListener() {
			// @Override
			// public void onClick(View v) {
			// // 取消升级
			// isCancel = true;
			// updateDialog.dismiss();
			// }
			// });
			updateDialog.show();

		}
		if (!updating) getLatestVersion();
		// handler.sendEmptyMessage(HANDLER_GET_LATEST_VERSION);
	} 

	/**
	 * @description：从服务器获取新版本信息
	 * @author samy
	 * @date 2014年10月9日 下午6:08:46
	 */
	private void getLatestVersion() {
		currentVerInfo = getCurrentVersionInfo();

		// 泛型的描述
		Type typeOfT = new TypeToken<RequestResult<VersionBean>>() {
		}.getType();

		FormResultRequest<VersionBean> formRequestResult = new FormResultRequest<VersionBean>(UrlConstants.GETVERSIONINFO, updateListener, updateErrorListener, typeOfT);
		JSONWrapAjaxParams ajaxParams = new JSONWrapAjaxParams();
		ajaxParams.putCommonTypeParam("versionNo", currentVerInfo.versionCode);
		ajaxParams.putStringTypeParam("packageName", currentVerInfo.packageName);
//		String [] kageName = currentVerInfo.packageName.split(".");
//		if (kageName!=null&&kageName.length>0) {
//			ajaxParams.putStringTypeParam("packageName",kageName[kageName.length-1]);
//		}else {
//			ajaxParams.putStringTypeParam("packageName","renrench");
//		}
		// 将参数添加到请求中
		formRequestResult.setRequestParams(ajaxParams);
		// 执行请求
		// 如果在activity或fragment中执行请求，调用executeRequest（）方法
		VolleyRequestManager.addRequest(formRequestResult, this);
	}

	// 版本更新回调
	private Listener<RequestResult<VersionBean>> updateListener = new Listener<RequestResult<VersionBean>>() {
		@Override
		public void onResponse(RequestResult<VersionBean> arg0) {
			DebugTool.debug("版本更新回调");
			updating = false;
			if (updateDialog != null && updateDialog.isShowing()) {
				updateDialog.dismiss();
			}
			if (isCancel) { return; }
			if (1 != arg0.flag && isZi) {
				Toast.makeText(context, arg0.msg, Toast.LENGTH_SHORT).show();
			}
			else {
				latestVerInfo = arg0.getRs();
				compareVersion();
			}
		}
	};

	// 版本更新异常
	private ErrorListener updateErrorListener = new ErrorListener() {
		@Override
		public void onErrorResponse(VolleyError error) {
			updating = false;
			DebugTool.debug("版本更新异常回调");
			String msg = "网络异常";
			if (error instanceof ServerFlagError) {
				msg = ((ServerFlagError) error).result.msg;
			}
			else if (error instanceof ServerJsonUnParseError) {
				try {
					String res = ((ServerJsonUnParseError) error).result;
					JSONObject jsonObject = new JSONObject(res);
					msg = jsonObject.getString("msg");
				}
				catch (JSONException e) {
					e.printStackTrace();
				}
			}
			else {
				try {
					if (error.networkResponse != null && error.networkResponse.data != null) msg = new String(error.networkResponse.data, "utf-8");
				}
				catch (UnsupportedEncodingException e) {
					e.printStackTrace();
				}
			}
			if (!isSilent() && isZi) {
				Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
			}

			if (updateDialog != null && updateDialog.isShowing()) {
				updateDialog.dismiss();
			}
			if (isCancel) { return; }
		}
	};

	/**
	 * @description：获取本地当前版本信息
	 * @author samy
	 * @date 2014年10月9日 下午6:09:08
	 */
	private PackageInfo getCurrentVersionInfo() {
		PackageManager pm = context.getPackageManager();
		// getPackageName()是你当前类的包名，0代表是获取版本信息
		try {
			PackageInfo packInfo = pm.getPackageInfo(context.getPackageName(), 0);
			return packInfo;
		}
		catch (Exception e) {
		}
		return null;
	}

	/**
	 * @description：由应用包名得到应用信息
	 * @author samy
	 * @date 2014年10月17日 下午3:02:58
	 */
	public static PackageInfo getPkgInfoByName(Context context, String pkgName) {
		PackageInfo pkgInfo = null;
		PackageManager pm = context.getPackageManager();
		try {
			// 0代表是获取版本信息
			pkgInfo = pm.getPackageInfo(pkgName, 0);
		}
		catch (Exception e) {
		}
		return pkgInfo;
	}

	/**
	 * @description：比较本地版本和服务器版本
	 * @author samy
	 * @date 2014年10月9日 下午6:09:17
	 */
	private void compareVersion() {
		if (updateDialog != null) {
			updateDialog.dismiss();
		}
		if (latestVerInfo == null || currentVerInfo == null) {// 获取版本信息失败
			if (!isSilent() && isZi) {
				Toast.makeText(context, "已经是最新版本", Toast.LENGTH_SHORT).show();
			}
			return;
		}
		if (Integer.parseInt(latestVerInfo.versionNo) <= currentVerInfo.versionCode) {// 无需更新
			if (!isSilent()) {
				// 弹出提示对话框 您已经是最新版本
				// MMAlert.createShowCenterCustomeDialog(context, titleStr, layoutId, leftStr, rightStr, leftClick, rightClick)
				// TODO
				// AlertDialog.Builder builder = new AlertDialog.Builder(context,R.style.VerSionDialogTheme);
				Dialog builder = new Dialog(context, R.style.VerSionDialogTheme);
				builder.setContentView(R.layout.dialog_update_isnew); 
				builder.show();
			}
			return;
		}
		else {// 有新版本
			try {
				String negativeText = "稍后更新";
				if (latestVerInfo.isForceUpdate == 1) { 
					negativeText = "退出";
				}

				String ver = context.getResources().getString(R.string.version, latestVerInfo.VersionName);
				String updateSize = context.getString(R.string.update_size, latestVerInfo.fileSize);
				String updateContent = context.getString(R.string.update_content, latestVerInfo.updateInfo);
				String updateTitle = context.getString(R.string.update_title, latestVerInfo.VersionName);
				// TODO 替换掉当前的默认对话框
				final Dialog dialog = new Dialog(context, R.style.VerSionDialogTheme);
				// final Dialog dialog = new Dialog(context);
				// dialog.setTitle("发现新版本");
				View view = View.inflate(context, R.layout.dialog_update_confirm, null);
				dialog.setContentView(view);
				dialog.setCancelable(latestVerInfo.isForceUpdate != 1);
				((TextView) view.findViewById(R.id.update_content)).setText(updateContent);
				view.findViewById(R.id.update_confirm).setOnClickListener(new View.OnClickListener() {
					@Override
					public void onClick(View view) {
						PreferencesHelper.getInstance().setString(PreferencesHelper.LAST_CHECK_VERSION, latestVerInfo.VersionName);
						// Uri uri = Uri.parse(latestVerInfo.downloadURL);
						// Intent intent = new Intent(Intent.ACTION_VIEW, uri);
						// context.startActivity(intent);
						dialog.dismiss();
						updateVersion();
					}
				});

				TextView negativeTv = (TextView) view.findViewById(R.id.update_cancle);
				negativeTv.setText(negativeText);
				negativeTv.setOnClickListener(new View.OnClickListener() {
					@Override
					public void onClick(View view) {
						dialog.dismiss();
						PreferencesHelper.getInstance().setLong(PreferencesHelper.LAST_VERSION_CHECK_TIME, System.currentTimeMillis());
						if (latestVerInfo.isForceUpdate == 1) {
							// 退出系统
							KJActivityManager.create().AppExit(context);
						}
					}
				});
				dialog.show();
			}
			catch (Exception e) {
			}
		}
	}

	/**
	 * @description：更新版本
	 * @author samy
	 * @date 2014年10月17日 下午3:03:39
	 */
	protected void updateVersion() { 
		File apkFile = new File(localDir, localFileName);
		/**
		 * 如果之前已经下载过就直接安装
		 */
		if (apkFile.exists()) {
			ApplicationInfo appInfo = getApkInfoByPath(context, apkFile.getAbsolutePath());
			if (appInfo != null && appInfo.packageName.equals(latestVerInfo.packageName)) {
				// 如果包名相同
				PackageInfo pkgInfo = getPkgInfoByName(context, appInfo.packageName);
				if (pkgInfo != null && pkgInfo.versionCode == Integer.parseInt(latestVerInfo.versionNo)) {
					// 如果版本号等于最新版本号
					try {
						// 直接跳到安装界面
						installApkByPath(context, apkFile.getCanonicalPath());
					}
					catch (Exception e) {
						Toast.makeText(context, "安装出错！", Toast.LENGTH_SHORT).show();
						apkFile.delete();
					}
					return;
				}
			}
		}
		File dir = new File(localDir);
		if (!dir.exists()) {
			dir.mkdirs();
		}
		/**
		 * 去下载安装；
		 */
		try {
			AlertDialog.Builder builder = new AlertDialog.Builder(context).setTitle("正在升级").setView(addLayout()).setCancelable(false);
			// 判断强制更新
			if (latestVerInfo.isForceUpdate != 1) {
				builder.setNegativeButton("取消", new OnClickListener() {
					@Override
					public void onClick(DialogInterface dialog, int which) {
						isCancel = true;// 取消下载
					}
				});
			}
			builder.show();
			downloadFile2(apkFile);
		}
		catch (Exception e) {
		}
	}

	/**
	 * @description：直接文件操作更新进度条；
	 * @author samy
	 * @date 2014年10月27日 上午9:58:02
	 */
	private void downloadFile2(final File saveFile) {
		new Thread(new Runnable() {
			@SuppressWarnings("resource")
			@Override
			public void run() {
				InputStream inStream = null;
				FileOutputStream fos = null; 
				try {
					// HttpResponse response = httpGetResponse(latestVerInfo.getDownloadURL(), false);
					// fileSize = httpGetFileLength(response);
					// if (fileSize > 0) {
					// Log.d("md", "fileSize:" + fileSize);
					// handler.sendEmptyMessage(HANDLER_DOWNLOAD_SIZE);
					// } else {
					// handler.sendEmptyMessage(HANDLER_DOWNLOAD_ERROR);
					// return;
					// }
					// inStream = httpGetInputStream(response);
					fileSize = Integer.parseInt(latestVerInfo.getFileSize().replace("byte", ""));
					if (fileSize > 0) {
						Log.d("md", "fileSize:" + fileSize);
						handler.sendEmptyMessage(HANDLER_DOWNLOAD_SIZE);
					}
					else {
						handler.sendEmptyMessage(HANDLER_DOWNLOAD_ERROR);
						return;
					}
					// TODO 测试用 暂时写死
					String fileName = latestVerInfo.getDownloadURL().substring(latestVerInfo.getDownloadURL().lastIndexOf("/") + 1);
					String downloadUrl = latestVerInfo.getDownloadURL();
					// downloadUrl=UrlConstants.HOST+downloadUrl;
					// String downloadUrl="http://192.168.16.218/im1/M00/00/0D/wKgQ2lSGu7eAGexqAD2hicj3gSI640.apk";
					URL url = new URL(downloadUrl);
					HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
					inStream = urlConn.getInputStream();

					fos = new FileOutputStream(saveFile);
					byte[] buffer = new byte[1024];
					int offset = 0;
					int sum = 0;

					while ((offset = inStream.read(buffer, 0, 1024)) != -1) {
						if (isCancel) {
							// 暂停退出
							handler.obtainMessage(HANDLER_DOWNLOAD_STOP).sendToTarget();
							return;
						}
						fos.write(buffer, 0, offset);
						sum += offset;
						handler.obtainMessage(HANDLER_DOWNLOAD_PROGRESS, sum, 0).sendToTarget();
					}
					if (sum == fileSize) {
						handler.sendEmptyMessage(HANDLER_DOWNLOAD_FINISH);
					}
					else {
						handler.obtainMessage(HANDLER_DOWNLOAD_ERROR, "下载文件不匹配！").sendToTarget();
					}
				}
				catch (Exception e) {
					handler.obtainMessage(HANDLER_DOWNLOAD_ERROR, "文件下载失败！").sendToTarget();
				}
				finally {
					try {
						if (fos != null) {
							fos.close();
						}
						if (inStream != null) {
							inStream.close();
						}
					}
					catch (Exception e) {
					}
				}
			}
		}).start();
	}

	//
	// /**
	// * @description：开始下载文件；直接文件操作更新进度条；用框架自带的断点续传功能实现；（目前发现有点问题）
	// * @author samy
	// * @date 2014年10月27日 上午9:58:02
	// */
	// private void downloadFile(final File apkFile) {
	// fileSize = Integer.parseInt(latestVerInfo.fileSize.replace("byte", ""));
	// downloadBar.setMax(fileSize);
	// KJHttp kjHttp = GlobalApp.getKJHttp();
	// FileCallBack fileCallBack = new FileCallBack() {
	// @Override
	// public void onSuccess(File file) {
	// installApkByPath(context, new File(localDir, localFileName).getAbsolutePath());
	// updateDialog.dismiss();
	// }
	//
	// @Override
	// public void onLoading(long count, long current) {
	// super.onLoading(count, current);
	// progressTv.setText(current * 100 / fileSize + "%");
	// downloadBar.setProgress((int) current * 100 / fileSize);
	// }
	//
	// @Override
	// public void onFailure(Throwable t, int errorNo, String strMsg) {
	// super.onFailure(t, errorNo, strMsg);
	// Toast.makeText(context, strMsg, Toast.LENGTH_SHORT).show();
	// apkFile.delete();
	// if (updateDialog != null && updateDialog.isShowing()) {
	// updateDialog.dismiss();
	// }
	// }
	// };
	// // 若要显示进度，必须设置为true
	// fileCallBack.setProgress(true);
	// kjHttp.urlDownload(latestVerInfo.downloadURL, apkFile, fileCallBack);
	// }

	/**
	 * @description： 由路径得到app信息
	 * @author samy
	 * @date 2014年10月17日 下午3:00:41
	 */
	public static ApplicationInfo getApkInfoByPath(Context context, String absPath) {
		ApplicationInfo appInfo = null;
		PackageManager pm = context.getPackageManager();
		PackageInfo pkgInfo = pm.getPackageArchiveInfo(absPath, PackageManager.GET_ACTIVITIES);
		if (pkgInfo != null) {
			appInfo = pkgInfo.applicationInfo;
			/* 必须加这两句，不然下面icon获取是default icon而不是应用包的icon */
			appInfo.sourceDir = absPath;
			appInfo.publicSourceDir = absPath;
		}
		return appInfo;
	}

	/**
	 * @description：由apk路径直接跳到安装界面
	 * @author samy
	 * @date 2014年10月17日 下午3:04:27
	 */
	public static void installApkByPath(Context context, String absPath) {
		chmod("777", absPath);
		Intent intent = new Intent(Intent.ACTION_VIEW);
		intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		intent.setDataAndType(Uri.parse("file://" + absPath), "application/vnd.android.package-archive");
		context.startActivity(intent);
		android.os.Process.killProcess(android.os.Process.myPid());// 如果不加上这句的话在apk安装完成之后点击单开会崩溃
	}

	public static void chmod(String permission, String path) {
		try {
			String command = "chmod " + permission + " " + path;
			Runtime.getRuntime().exec(command);
		}
		catch (IOException e) {
			e.printStackTrace();
		}
	}

	public boolean isSilent() {
		synchronized (lock) {
			return isSilent;
		}
	}

	public void setSilent(boolean isSilent) {
		synchronized (lock) {
			this.isSilent = isSilent;
		}
	}

	public RelativeLayout addLayout() {
		RelativeLayout relativeLayout = new RelativeLayout(context);
		TextView textView = new TextView(context);
		textView.setId(1);
		textView.setTextSize(15);
		textView.setTextColor(Color.BLACK);
		textView.setText("下载进度:");
		RelativeLayout.LayoutParams layoutParams1 = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
		layoutParams1.addRule(RelativeLayout.ALIGN_PARENT_TOP);
		layoutParams1.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);
		layoutParams1.setMargins(10, 10, 10, 10);
		relativeLayout.addView(textView, layoutParams1);

		progressTv = new TextView(context);
		progressTv.setId(2);
		progressTv.setTextSize(15);
		progressTv.setTextColor(Color.BLACK);
		RelativeLayout.LayoutParams layoutParams2 = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
		layoutParams2.addRule(RelativeLayout.RIGHT_OF, 1);
		layoutParams2.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE);
		layoutParams2.setMargins(0, 10, 10, 10);
		relativeLayout.addView(progressTv, layoutParams2);

		downloadBar = new ProgressBar(context);
		downloadBar.setId(3);
		downloadBar.setMax(100);
		downloadBar.setProgress(25);
		downloadBar.setMinimumHeight(20);
		ProgressBeanUtil.setFieldValue(downloadBar, "mOnlyIndeterminate", new Boolean(false));
		downloadBar.setIndeterminate(false);
		downloadBar.setProgressDrawable(context.getResources().getDrawable(R.drawable.progress_bar_states));
		// downloadBar.setProgressDrawable(context.getResources().getDrawable(android.R.drawable.progress_horizontal));
		downloadBar.setIndeterminateDrawable(context.getResources().getDrawable(android.R.drawable.progress_indeterminate_horizontal));
		RelativeLayout.LayoutParams layoutParams3 = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 20);

		layoutParams3.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE);
		layoutParams3.addRule(RelativeLayout.BELOW, 1);
		layoutParams3.setMargins(10, 10, 10, 10);
		relativeLayout.addView(downloadBar, layoutParams3);
		return relativeLayout;
	}
}